﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Stone
{
    //class NMEA
    //{

        //      $GPVTG,330.0,T,,M,014.5,N,026.8,K,N*0E
        //      $GPGGA,154005.138,4529.4440,N,00914.2673,E,0,00,2.5,313.8,M,45.9,M,,0000*56
        //      $GPGSA,A,1,,,,,,,,,,,,,2.6,2.5,0.8*3B
        //      $GPRMC,154005.138,V,4529.4440,N,00914.2673,E,014.5,330.0,230810,,,N*73
        //      $GPGSV,3,1,12,21,61,171,30,29,54,061,,31,44,229,,16,35,306,*7A 






        //      $GP VTG: Velocity made good. The gps receiver may use the LC prefix instead of GP if it is emulating Loran output. 

                        //  $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48

                        //where:
                        //        VTG          Track made good and ground speed
                        //        054.7,T      True track made good (degrees)
                        //        034.4,M      Magnetic track made good
                        //        005.5,N      Ground speed, knots
                        //        010.2,K      Ground speed, Kilometers per hour
                        //        *48          Checksum

                        //Note that, as of the 2.3 release of NMEA, there is a new field in the VTG sentence at the end just prior to the checksum. For more information on this field see here. 

                        //Receivers that don't have a magnetic deviation (variation) table built in will null out the Magnetic track made good. 


        //      $GP GGA: essential fix data which provide 3D location and accuracy data. 

                        // $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

                        //Where:
                        //     GGA          Global Positioning System Fix Data
                        //     123519       Fix taken at 12:35:19 UTC
                        //     4807.038,N   Latitude 48 deg 07.038' N
                        //     01131.000,E  Longitude 11 deg 31.000' E
                        //     1            Fix quality: 0 = invalid
                        //                               1 = GPS fix (SPS)
                        //                               2 = DGPS fix
                        //                               3 = PPS fix
                        //                   4 = Real Time Kinematic
                        //                   5 = Float RTK
                        //                               6 = estimated (dead reckoning) (2.3 feature)
                        //                   7 = Manual input mode
                        //                   8 = Simulation mode
                        //     08           Number of satellites being tracked
                        //     0.9          Horizontal dilution of position
                        //     545.4,M      Altitude, Meters, above mean sea level
                        //     46.9,M       Height of geoid (mean sea level) above WGS84
                        //                      ellipsoid
                        //     (empty field) time in seconds since last DGPS update
                        //     (empty field) DGPS station ID number
                        //     *47          the checksum data, always begins with *

                        //If the height of geoid is missing then the altitude should be suspect. Some non-standard implementations report altitude with respect to the ellipsoid rather than geoid altitude. Some units do not report negative altitudes at all. This is the only sentence that reports altitude. 



        //      $GP GSA - GPS DOP and active satellites. This sentence provides details on the nature of the fix. 
        //                It includes the numbers of the satellites being used in the current solution and the DOP. 
        //                DOP (dilution of precision) is an indication of the effect of satellite geometry on the accuracy of the fix. It is a unitless number 
        //                where smaller is better. For 3D fixes using 4 satellites a 1.0 would be considered to be a perfect number, however for overdetermined 
        //                solutions it is possible to see numbers below 1.0. 

        //                There are differences in the way the PRN's are presented which can effect the ability of some programs to display this data. For example, 
        //                in the example shown below there are 5 satellites in the solution and the null fields are scattered indicating that the almanac would show 
        //                satellites in the null positions that are not being used as part of this solution. Other receivers might output all of the satellites used 
        //                at the beginning of the sentence with the null field all stacked up at the end. This difference accounts for some satellite display programs 
        //                not always being able to display the satellites being tracked. Some units may show all satellites that have ephemeris data without regard to 
        //                their use as part of the solution but this is non-standard. 

        //                  $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

        //                  Where:
        //                      GSA      Satellite status
        //                       A        Auto selection of 2D or 3D fix (M = manual) 
        //                       3        3D fix - values include: 1 = no fix
        //                                       2 = 2D fix
        //                                       3 = 3D fix
        //                       04,05... PRNs of satellites used for fix (space for 12) 
        //                       2.5      PDOP (dilution of precision) 
        //                       1.3      Horizontal dilution of precision (HDOP) 
        //                       2.1      Vertical dilution of precision (VDOP)
        //                       *39      the checksum data, always begins with *


        //      $GP RMC: NMEA has its own version of essential gps pvt (position, velocity, time) data. It is called RMC, The Recommended Minimum, which will look similar to: 

                        //$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

                        //Where:
                        //     RMC          Recommended Minimum sentence C
                        //     123519       Fix taken at 12:35:19 UTC
                        //     A            Status A=active or V=Void.
                        //     4807.038,N   Latitude 48 deg 07.038' N
                        //     01131.000,E  Longitude 11 deg 31.000' E
                        //     022.4        Speed over the ground in knots
                        //     084.4        Track angle in degrees True
                        //     230394       Date - 23rd of March 1994
                        //     003.1,W      Magnetic Variation
                        //     *6A          The checksum data, always begins with *

                        //Note that, as of the 2.3 release of NMEA, there is a new field in the RMC sentence at the end just prior to the checksum. 
                        //For more information on this field see here. 


        //      $GP GSV: Satellites in View shows data about the satellites that the unit might be able to find based on its viewing mask and almanac data. 
                        //It also shows current ability to track this data. Note that one GSV sentence only can provide data for up to 4 satellites and 
                        //thus there may need to be 3 sentences for the full information. It is reasonable for the GSV sentence to contain more satellites 
                        //than GGA might indicate since GSV may include satellites that are not used as part of the solution. It is not a requirment that 
                        //the GSV sentences all appear in sequence. To avoid overloading the data bandwidth some receivers may place the various 
                        //sentences in totally different samples since each sentence identifies which one it is. 

                        //The field called SNR (Signal to Noise Ratio) in the NMEA standard is often referred to as signal strength. SNR is an indirect 
                        //but more useful value that raw signal strength. It can range from 0 to 99 and has units of dB according to the NMEA standard, 
                        //but the various manufacturers send different ranges of numbers with different starting numbers so the values themselves cannot 
                        //necessarily be used to evaluate different units. The range of working values in a given gps will usually show a difference of 
                        //about 25 to 35 between the lowest and highest values, however 0 is a special case and may be shown on satellites that are in 
                        //view but not being tracked. 

                        //  $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

                        //Where:
                        //      GSV          Satellites in view
                        //      2            Number of sentences for full data
                        //      1            sentence 1 of 2
                        //      08           Number of satellites in view

                        //      01           Satellite PRN number
                        //      40           Elevation, degrees
                        //      083          Azimuth, degrees
                        //      46           SNR - higher is better
                        //           for up to 4 satellites per sentence
                        //      *75          the checksum data, always begins with *






        //#region NMEAParser

        //// Processes information from the GPS receiver
        //public bool Parse(string sentence)
        //{
        //    // Discard the sentence if its checksum does not match our calculated checksum
        //    if (!IsValid(sentence)) return false;

        //    // strip off checksum marker
        //    sentence = sentence.Substring(0, sentence.IndexOf("*"));

        //    // Look at the first word to decide where to go next
        //    switch (GetWords(sentence)[0])
        //    {
        //        case "$GPRMC":
        //            // A "Recommended Minimum" sentence was found!
        //            return ParseGPRMC(sentence);
        //        case "$GPGSV":
        //            // A "Satellites in View" sentence was recieved
        //            return ParseGPGSV(sentence);
        //        case "$GPGSA":
        //            return ParseGPGSA(sentence);
        //        default:
        //            // Indicate that the sentence was not recognized
        //            return false;
        //    }
        //}

        //// Divides a sentence into individual words
        //public string[] GetWords(string sentence)
        //{
        //    return sentence.Split(',');
        //}

        //// Interprets a $GPRMC message
        //public bool ParseGPRMC(string sentence)
        //{
        //    // Divide the sentence into words
        //    string[] Words = GetWords(sentence);
        //    // Do we have enough values to describe our location?
        //    if (Words[3] != "" & Words[4] != "" & Words[5] != "" & Words[6] != "")
        //    {
        //        // Yes. Extract latitude and longitude
        //        string Latitude = Words[3].Substring(0, 2) + "°"; // Append hours
        //        Latitude = Latitude + Words[3].Substring(2) + "\""; // Append minutes
        //        Latitude = Latitude + Words[4]; // Append the hemisphere
        //        string Longitude = Words[5].Substring(0, 3) + "°"; // Append hours
        //        Longitude = Longitude + Words[5].Substring(3) + "\""; // Append minutes
        //        Longitude = Longitude + Words[6]; // Append the hemisphere                
        //    }
        //    // Do we have enough values to parse satellite-derived time?
        //    if (Words[1] != "")
        //    {
        //        // Yes. Extract hours, minutes, seconds and milliseconds
        //        int UtcHours = Convert.ToInt32(Words[1].Substring(0, 2));
        //        int UtcMinutes = Convert.ToInt32(Words[1].Substring(2, 2));
        //        int UtcSeconds = Convert.ToInt32(Words[1].Substring(4, 2));
        //        int UtcMilliseconds = 0;
        //        // Extract milliseconds if it is available
        //        if (Words[1].Length > 7)
        //        {
        //            UtcMilliseconds = Convert.ToInt32(Words[1].Substring(7));
        //        }
        //        // Now build a DateTime object with all values
        //        System.DateTime Today = System.DateTime.Now.ToUniversalTime();
        //        System.DateTime SatelliteTime = new System.DateTime(Today.Year, Today.Month, Today.Day, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds);
                
        //    }
        //    // Do we have enough information to extract the current speed?
        //    if (Words[7] != "")
        //    {
        //        // Yes.  Parse the speed and convert it to MPH
        //        double Speed = double.Parse(Words[7], NmeaCultureInfo) * MPHPerKnot;                
        //    }
        //    // Do we have enough information to extract bearing?
        //    if (Words[8] != "")
        //    {
        //        // Indicate that the sentence was recognized
        //        double Bearing = double.Parse(Words[8], NmeaCultureInfo);                
        //    }
        //    // Does the device currently have a satellite fix?
        //    if (Words[2] != "")
        //    {
        //        switch (Words[2])
        //        {
        //            case "A":
        //                if (FixObtained != null)
        //                    FixObtained();
        //                break;
        //            case "V":
        //                if (FixLost != null)
        //                    FixLost();
        //                break;
        //        }
        //    }
        //    // Indicate that the sentence was recognized
        //    return true;
        //}

        //// Interprets a "Satellites in View" NMEA sentence
        //public bool ParseGPGSV(string sentence)
        //{
        //    int PseudoRandomCode = 0;
        //    int Azimuth = 0;
        //    int Elevation = 0;
        //    int SignalToNoiseRatio = 0;
        //    // Divide the sentence into words
        //    string[] Words = GetWords(sentence);
        //    // Each sentence contains four blocks of satellite information.  Read each block
        //    // and report each satellite's information
        //    int Count = 0;
        //    for (Count = 1; Count <= 4; Count++)
        //    {
        //        // Does the sentence have enough words to analyze?
        //        if ((Words.Length - 1) >= (Count * 4 + 3))
        //        {
        //            // Yes.  Proceed with analyzing the block.  Does it contain any information?
        //            if (Words[Count * 4] != "" & Words[Count * 4 + 1] != "" & Words[Count * 4 + 2] != "" & Words[Count * 4 + 3] != "")
        //            {
        //                // Yes. Extract satellite information and report it
        //                PseudoRandomCode = System.Convert.ToInt32(Words[Count * 4]);
        //                Elevation = Convert.ToInt32(Words[Count * 4 + 1]);
        //                Azimuth = Convert.ToInt32(Words[Count * 4 + 2]);
        //                SignalToNoiseRatio = Convert.ToInt32(Words[Count * 4 + 2]);                        
        //            }
        //        }
        //    }
        //    // Indicate that the sentence was recognized
        //    return true;
        //}

        //// Interprets a "Fixed Satellites and DOP" NMEA sentence
        //public bool ParseGPGSA(string sentence)
        //{
        //    // Divide the sentence into words
        //    string[] Words = GetWords(sentence);
        //    // Update the DOP values
        //    if (Words[15] != "")
        //    {
        //        if (PDOPReceived != null)
        //            PDOPReceived(double.Parse(Words[15], NmeaCultureInfo));
        //    }
        //    if (Words[16] != "")
        //    {
        //        if (HDOPReceived != null)
        //            HDOPReceived(double.Parse(Words[16], NmeaCultureInfo));
        //    }
        //    if (Words[17] != "")
        //    {
        //        if (VDOPReceived != null)
        //            VDOPReceived(double.Parse(Words[17], NmeaCultureInfo));
        //    }
        //    return true;
        //}

        //// Returns True if a sentence's checksum matches the calculated checksum
        //public bool IsValid(string sentence)
        //{
        //    // Compare the characters after the asterisk to the calculation
        //    return sentence.Substring(sentence.IndexOf("*") + 1) == GetChecksum(sentence);
        //}

        //// Calculates the checksum for a sentence
        //public string GetChecksum(string sentence)
        //{
        //    // Loop through all chars to get a checksum
        //    //INSTANT C# NOTE: Commented this declaration since looping variables in 'foreach' loops are declared in the 'foreach' header in C#
        //    //        char Character = '\0';
        //    int Checksum = 0;
        //    foreach (char Character in sentence)
        //    {
        //        if (Character == '$')
        //        {
        //            // Ignore the dollar sign
        //        }
        //        else if (Character == '*')
        //        {
        //            // Stop processing before the asterisk
        //            break;
        //        }
        //        else
        //        {
        //            // Is this the first value for the checksum?
        //            if (Checksum == 0)
        //            {
        //                // Yes. Set the checksum to the value
        //                Checksum = Convert.ToByte(Character);
        //            }
        //            else
        //            {
        //                // No. XOR the checksum with this character's value
        //                Checksum = Checksum ^ Convert.ToByte(Character);
        //            }
        //        }
        //    }
        //    // Return the checksum formatted as a two-character hexadecimal
        //    return Checksum.ToString("X2");
        //}

        //#endregion


    //}
}
